@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sh:   <http://www.w3.org/ns/shacl#> .
@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/>.
@prefix ex:  <http://example.org/> .

# Sequence path
ex:SequencePathShape a sh:NodeShape ;
    sh:property [
        sh:path (ex:p1 ex:p2 ) ;
        sh:minCount 1
    ] .

# Optional sequence path
ex:OptionalSequencePathShape a sh:NodeShape ;
    sh:property [
        sh:path (ex:p1 ex:p2 ) ;
        sh:minCount 0
    ] .

# Inverse path
ex:InversePathShape a sh:NodeShape ;
    sh:property [
        sh:path [sh:inversePath ex:p2 ] ;
        sh:minCount 1
    ] .

# Optional inverse path
ex:OptionalInversePathShape a sh:NodeShape ;
    sh:property [
        sh:path [sh:inversePath ex:p2 ] ;
        sh:minCount 0
    ] .

# Sequence and inverse path
ex:SequenceAndInversePathShape a sh:NodeShape ;
    sh:property [
        sh:path ([sh:inversePath ex:p2 ] ex:p1 ) ;
        sh:minCount 1
    ] .

# Double inverse path
ex:DoubleInversePathShape a sh:NodeShape ;
    sh:closed true;
    sh:property [
        sh:path ([sh:inversePath [sh:inversePath ex:p1 ] ]) ;
        sh:minCount 1
    ] .

# Triple inverse path
ex:TripleInversePathShape a sh:NodeShape ;
    sh:closed true;
    sh:property [
        sh:path ([sh:inversePath [sh:inversePath [sh:inversePath ex:p1 ] ] ]) ;
        sh:minCount 1
    ] .

# Quadruple inverse path
ex:QuadrupleInversePathShape a sh:NodeShape ;
    sh:closed true;
    sh:property [
        sh:path ([sh:inversePath [sh:inversePath [sh:inversePath [sh:inversePath ex:p1 ] ] ] ]) ;
        sh:minCount 1
    ] .

# Zero or More path
ex:ZeroOrMorePathShape a sh:NodeShape ;
    sh:closed true;
    sh:property [
        sh:path ([sh:zeroOrMorePath ex:p1 ]) ;
        sh:minCount 1
    ] .

ex:OneOrMorePathShape a sh:NodeShape ;
    sh:closed true;
    sh:property [
        sh:path ([sh:oneOrMorePath ex:p1 ]) ;
        sh:minCount 1
    ] .

ex:ZeroOrOnePathShape a sh:NodeShape ;
    sh:closed true;
    sh:property [
        sh:path (ex:p1 [sh:zeroOrOnePath ex:p2 ]) ;
        sh:minCount 1
    ] .

ex:AlternativePathShape a sh:NodeShape ;
    sh:closed true;
    sh:property [
        sh:path ([sh:alternativePath (ex:p1 ex:p2)]) ;
        sh:minCount 1
    ] .


ex:AllTogetherPathShape a sh:NodeShape ;
    sh:closed true;
    sh:property [
        sh:path ([sh:alternativePath ([ sh:inversePath ex:p1 ] ex:p2)]) ;
        sh:minCount 1
    ] .

# Nested shape
ex:NestedShape a sh:NodeShape ;
    sh:property [
        sh:path ex:subject ;
        sh:minCount 1 ;
        sh:node [
            rdfs:label "SecondNestedShape" ;
            sh:property [
                sh:path rdfs:label ;
                sh:minCount 1
            ]
        ]
    ] .

ex:XoneWithNodeShape a sh:NodeShape ;
	sh:xone ( [
		sh:path foaf:name;
		sh:minCount 1
	] [
        rdfs:label "SecondXoneWithNodeShape" ;
		sh:property [
			sh:path ex:qualifiedName ;
			sh:node ex:QualifiedNameShape;
			sh:minCount 1
		]
	]) .


ex:XoneWithNodeShape2 a sh:NodeShape ;
	sh:xone ( [
		sh:path foaf:name;
		sh:minCount 1
	] [
         rdfs:label "SecondXoneWithNodeShape2" ;
		sh:property [
			sh:path ex:qualifiedName ;
			sh:node ex:QualifiedNameShape2;
			sh:minCount 1
		]
	]) .

ex:QualifiedNameShape2 a sh:NodeShape ;
	sh:property [
		sh:minCount 1 ;
		sh:path ex:name ;
	], [
		sh:path ex:validUntil ;
		# ...
	] .

# Nested shape with optional path
ex:NestedWithOptionalShape a sh:NodeShape ;
    sh:property [
        sh:path ex:subject ;
        sh:minCount 0 ;
        sh:node [
            rdfs:label "OptionalNestedNodeShape" ;
            sh:property [
                sh:path rdfs:label ;
                sh:minCount 1
            ]
        ]
    ] .

# Shape with sh:targetClass and sh:datatype properties
ex:LabeledShape a sh:NodeShape ;
    sh:targetClass ex:Person ;
    sh:property [
        sh:path ex:label ;
        sh:datatype xsd:string ;
        sh:minCount 1
    ] .
